package org.zoomdev.zoom;

import java.io.Serializable;
import java.util.*;
import java.util.concurrent.ThreadLocalRandom;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

public class EmployeeDataGenerator {

    // 预定义数据池
    private static final String[] FIRST_NAMES = {
            "James", "Mary", "John", "Patricia", "Robert", "Jennifer", "Michael", "Linda",
            "William", "Elizabeth", "David", "Barbara", "Richard", "Susan", "Joseph", "Jessica",
            "Thomas", "Sarah", "Charles", "Karen", "Christopher", "Lisa", "Daniel", "Nancy",
            "Matthew", "Betty", "Anthony", "Margaret", "Mark", "Sandra"
    };

    private static final String[] LAST_NAMES = {
            "Smith", "Johnson", "Williams", "Brown", "Jones", "Garcia", "Miller", "Davis",
            "Rodriguez", "Martinez", "Hernandez", "Lopez", "Gonzalez", "Wilson", "Anderson",
            "Thomas", "Taylor", "Moore", "Jackson", "Martin", "Lee", "Perez", "Thompson",
            "White", "Harris", "Sanchez", "Clark", "Ramirez", "Lewis", "Robinson", "Walker"
    };

    private static final String[] DEPARTMENTS = {
            "Engineering", "Marketing", "Sales", "Human Resources", "Finance",
            "IT", "Operations", "Customer Support", "Research & Development", "Legal"
    };

    private static final String[] JOB_TITLES = {
            "Software Engineer", "Senior Developer", "DevOps Specialist", "QA Engineer",
            "Product Manager", "Marketing Analyst", "Sales Representative", "HR Coordinator",
            "Financial Analyst", "System Administrator", "Operations Manager", "Support Specialist",
            "Research Scientist", "Legal Counsel", "UX Designer", "Data Scientist"
    };

    private static final String[] EMAIL_DOMAINS = {
            "gmail.com", "yahoo.com", "hotmail.com", "outlook.com", "company.com",
            "enterprise.io", "business.org", "techcorp.net"
    };

    // 生成单个随机Employee
    public static Employee generateRandomEmployee(int id) {
        ThreadLocalRandom random = ThreadLocalRandom.current();

        // 随机生成名字
        String firstName = FIRST_NAMES[random.nextInt(FIRST_NAMES.length)];
        String lastName = LAST_NAMES[random.nextInt(LAST_NAMES.length)];

        // 生成邮箱
        String email = firstName.toLowerCase() + "." + lastName.toLowerCase() + "@" +
                EMAIL_DOMAINS[random.nextInt(EMAIL_DOMAINS.length)];

        // 随机部门和工作职称
        String department = DEPARTMENTS[random.nextInt(DEPARTMENTS.length)];
        String jobTitle = JOB_TITLES[random.nextInt(JOB_TITLES.length)];

        // 薪资范围（基于部门和职称）
        double salary = generateSalary(department, jobTitle);

        // 雇佣日期（过去1-15年）
        Date hireDate = generateHireDate(random);

        // 工作经验（1-30年）
        int yearsOfExperience = random.nextInt(1, 31);

        // 是否在职（85%概率在职）
        boolean active = random.nextDouble() < 0.85;

        return new Employee(
                id,
                firstName,
                lastName,
                email,
                department,
                salary,
                hireDate,
                active,
                yearsOfExperience,
                jobTitle
        );
    }

    // 生成薪资（基于部门和职称）
    private static double generateSalary(String department, String jobTitle) {
        ThreadLocalRandom random = ThreadLocalRandom.current();
        double baseSalary;

        // 根据部门设置基础薪资范围
        switch (department) {
            case "Engineering":
            case "Data Science":
                baseSalary = random.nextDouble(70_000, 160_000);
                break;
            case "Finance":
            case "Legal":
                baseSalary = random.nextDouble(65_000, 150_000);
                break;
            case "Marketing":
            case "Sales":
                baseSalary = random.nextDouble(50_000, 130_000);
                break;
            default:
                baseSalary = random.nextDouble(40_000, 100_000);
        }

        // 根据职称调整薪资
        if (jobTitle.contains("Senior") || jobTitle.contains("Manager")) {
            baseSalary *= 1.3;
        } else if (jobTitle.contains("Lead") || jobTitle.contains("Director")) {
            baseSalary *= 1.6;
        } else if (jobTitle.contains("Junior") || jobTitle.contains("Assistant")) {
            baseSalary *= 0.8;
        }

        // 四舍五入到百位
        return Math.round(baseSalary / 100) * 100;
    }

    // 生成雇佣日期
    private static Date generateHireDate(ThreadLocalRandom random) {
        // 随机年份（2008-2023）
        int year = random.nextInt(2008, 2024);

        // 随机月份（1-12）
        int month = random.nextInt(1, 13);

        // 随机日期（根据月份）
        int maxDay = 31;
        if (month == 2) {
            maxDay = 28; // 不考虑闰年
        } else if (month == 4 || month == 6 || month == 9 || month == 11) {
            maxDay = 30;
        }
        int day = random.nextInt(1, maxDay + 1);

        // 创建日期对象
        Calendar cal = Calendar.getInstance();
        cal.set(year, month - 1, day); // 月份从0开始
        return cal.getTime();
    }

    // 生成多个Employee
    public static List<Employee> generateEmployees(int count) {
        return IntStream.rangeClosed(1, count)
                .parallel()
                .mapToObj(EmployeeDataGenerator::generateRandomEmployee)
                .collect(Collectors.toList());
    }

    // 生成部门分布统计
    public static Map<String, Long> departmentDistribution(List<Employee> employees) {
        return employees.stream()
                .collect(Collectors.groupingBy(Employee::getDepartment, Collectors.counting()));
    }

    // 生成薪资统计
    public static Map<String, Double> salaryStatistics(List<Employee> employees) {
        Map<String, Double> stats = new LinkedHashMap<>();

        DoubleSummaryStatistics summary = employees.stream()
                .mapToDouble(Employee::getSalary)
                .summaryStatistics();

        stats.put("最低薪资", summary.getMin());
        stats.put("最高薪资", summary.getMax());
        stats.put("平均薪资", summary.getAverage());
        stats.put("薪资中位数", calculateMedianSalary(employees));

        return stats;
    }

    // 计算薪资中位数
    private static double calculateMedianSalary(List<Employee> employees) {
        List<Double> salaries = employees.stream()
                .map(Employee::getSalary)
                .sorted()
                .collect(Collectors.toList());

        int size = salaries.size();
        if (size % 2 == 0) {
            return (salaries.get(size/2 - 1) + salaries.get(size/2)) / 2.0;
        } else {
            return salaries.get(size/2);
        }
    }

    // 测试方法
    public static void main(String[] args) {
        // 生成1000个员工
        List<Employee> employees = generateEmployees(1000);

        // 打印前5个员工信息
        System.out.println("===== 前5名员工样例 =====");
        employees.stream().limit(5).forEach(System.out::println);

        // 部门分布统计
        System.out.println("\n===== 部门分布 =====");
        departmentDistribution(employees).forEach((dept, count) ->
                System.out.printf("%-20s: %d 人 (%.1f%%)\n",
                        dept, count, (count * 100.0 / employees.size()))
        );

        // 薪资统计
        System.out.println("\n===== 薪资统计 =====");
        salaryStatistics(employees).forEach((stat, value) ->
                System.out.printf("%-10s: $%,.2f\n", stat, value)
        );

        // 在职状态统计
        long activeCount = employees.stream().filter(Employee::isActive).count();
        System.out.printf("\n在职员工: %d (%.1f%%)\n",
                activeCount, (activeCount * 100.0 / employees.size()));
        System.out.printf("离职员工: %d (%.1f%%)\n",
                employees.size() - activeCount,
                ((employees.size() - activeCount) * 100.0 / employees.size()));
    }
}